/* eslint-disable vue/script-setup-uses-vars */
<template>
  <el-row :gutter="15">
    <el-form
      ref="formRef"
      :model="form"
      :label-width="formPattern.labelWidth"
      :rules="rules"
      label-position="right"
      v-if="form != undefined && formPattern.formItem != undefined"
    >
      <div v-for="(item, index) in formPattern.formItem" :key="index">
        <div v-if="item.type != 'multi' && item.type != 'form-item-list'">
          <el-row :gutter="15">
            <el-col
              v-for="(subItem, subIndex) in item"
              :key="subIndex"
              :span="24 / item.length"
            >
              <el-form-item
                :label="subItem.label + ':'"
                :prop="subItem.prop"
                label-width="150px"
              >
                <!-- el-input -->
                <!-- vue传递属性时如果没有.sync修饰符，默认不允许在子组件中修改属性，而v-model也算是一种修改
如果属性是一个对象，修改对象的属性也算是修改，v-model改为:value即可 -->
                <el-input
                  v-if="subItem.type === 'el-input'"
                  v-model="form[subItem.prop]"
                  :placeholder="subItem.placeholder"
                  :disabled="subItem.isReadOnly"
                ></el-input>
                <el-input-number
                  style="width:100%"
                  v-if="subItem.type == 'el-input-number'"
                  v-model="form[subItem.prop]"
                  :placeholder="subItem.placeholder"
                  :disabled="subItem.isReadOnly"
                  :controls="false"
                  :precision="
                    subItem.precision != undefined ? subItem.precision : 2
                  "
                  :max="subItem.max"
                  :min="subItem.min"
                ></el-input-number>
                <!--  <el-autpcomplete> -->
                <el-autocomplete
                  style="width:100%"
                  v-if="subItem.type === 'el-autocomplete'"
                  v-model="form[subItem.prop]"
                  :fetch-suggestions="
                    (queryString, cb) =>
                      querySearch(
                        queryString,
                        cb,
                        subItem.prop,
                        subItem.type,
                        formPattern.formType,
                        index
                      )
                  "
                >
                  <template #suffix>
                    <i class="el-icon-edit el-input__icon"> </i>
                  </template>
                  <!-- <template #default="{ subItem }">
                    <span>{{ subItem.value }}</span>
                  </template> -->
                </el-autocomplete>
                <!-- el-date-picker -->
                <el-date-picker
                  style="width:100%"
                  v-if="subItem.type === 'el-date-picker'"
                  v-model="form[subItem.prop]"
                  type="date"
                >
                </el-date-picker>
                <!-- el-select -->
                <el-select
                  style="width:100%"
                  collapse-tags
                  v-if="subItem.type === 'el-select'"
                  v-model="form[subItem.prop]"
                >
                  <el-option
                    v-for="option in subItem.options"
                    :key="option.value"
                    :label="option.label"
                    :value="option.value"
                  ></el-option>
                </el-select>
                <!-- el-cascader -->
                <el-cascader
                  style="width:100%"
                  v-if="subItem.type == 'el-cascader'"
                  :options="subItem.options"
                  v-model="form[subItem.prop]"
                  :props="{ checkStrictly: true }"
                  @change="
                    val => {
                      changeCascader(val);
                    }
                  "
                ></el-cascader>
                <!-- end -->
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <!-- landingAgency and partner -->
        <!-- 刚开始offsetList不存在？ -->
        <div class="multi-form-item" v-else-if="item.type == 'multi'">
          <el-button
            plain
            type="info"
            @click="addMultiItem(item.prop)"
            style="margin: 0 0 20px 30px;"
            v-if="item.isShowAddButton"
            >{{ item.label }}</el-button
          >
          <!-- 没有数据的时候不渲染该组件，这样不会出现unexpected width的bug -->
          <div
            v-if="
              form[item.prop] != undefined &&
                form[item.prop]?.length != undefined
            "
          >
            <el-row
              v-for="(multiDataItem, rowIndex) in form[item.prop]"
              :key="rowIndex.key"
              :gutter="0"
            >
              <!-- 行里面的每个formItem-->
              <!-- e.g (col, 0) in [agencyName, shareRadio] -->
              <!-- KNOW THAT activateDataItem is a OBJECT!!! -->
              <el-col
                v-for="(keyName, keyIndex) in item.keyList"
                :key="keyIndex.key"
                :span="item.spanList[keyIndex]"
              >
                <!-- if want to add some text after a item -->
                <span v-if="item.itemType[keyIndex] === 'text'">{{
                  item.labelList[keyIndex]
                }}</span>
                <!-- col里面的form-item -->
                <!-- eg prop= landingAgencies.0.agencyName -->
                <el-form-item
                  :label="item.labelList[keyIndex] + ':'"
                  :prop="`${item.prop}.${rowIndex}.${keyName}`"
                  :rules="rules.subRule[keyName]"
                  label-width="100px"
                  v-if="item.itemType[keyIndex] !== 'text'"
                >
                  <!-- e.g v-model="landingAgency[0].agencyName" -->
                  <el-input
                    v-model="multiDataItem[keyName]"
                    :disabled="item.isDisabled[keyIndex]"
                    v-if="item.itemType[keyIndex] === 'el-input'"
                    clearable
                  ></el-input>
                  <el-input-number
                    v-model="multiDataItem[keyName]"
                    :disabled="item.isDisabled[keyIndex]"
                    v-if="item.itemType[keyIndex] === 'el-input-number'"
                    :precision="2"
                    :controls="false"
                    :min="0"
                    :max="100"
                    clearable
                  ></el-input-number>
                  <!-- el-autocomplete -->
                  <el-autocomplete
                    v-model="multiDataItem[keyName]"
                    clearable
                    v-if="item.itemType[keyIndex] === 'el-autocomplete'"
                    :fetch-suggestions="
                      (queryString, cb) =>
                        querySearch(
                          queryString,
                          cb,
                          keyName,
                          item.type,
                          formPattern.formType,
                          rowIndex
                        )
                    "
                  ></el-autocomplete>
                  <!-- el-date-picker -->
                  <el-date-picker
                    v-if="item.itemType[keyIndex] === 'el-date-picker'"
                    v-model="multiDataItem[keyName]"
                    type="date"
                    style="width:150px"
                  >
                  </el-date-picker>
                  <!-- el-select -->
                  <el-select
                    collapse-tags
                    v-if="item.itemType[keyIndex] === 'el-select'"
                    v-model="multiDataItem[keyName]"
                    :disabled="item.isDisabled[keyIndex]"
                    @change="
                      nowVal =>
                        changeSelect(nowVal, item.prop, rowIndex, keyName)
                    "
                    @focus="saveSlectPreval(multiDataItem[keyName])"
                  >
                    <el-option
                      v-for="subOption in item.subOptions[keyName]"
                      :key="subOption.value"
                      :label="subOption.label"
                      :value="subOption.value"
                    ></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <!-- delete button -->
              <el-col :span="1" :offset="1">
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  style="margin-left: 15px"
                  @click.prevent="deleteMultiItem(item.prop, rowIndex)"
                  :disabled="form[item.prop]?.length <= 1"
                ></el-button>
              </el-col>
            </el-row>
          </div>
        </div>
        <!-- 只用过修改落地机构的返款时间.根据数据的不同会渲染不同个数的form-item -->
        <div
          v-else-if="
            item.type == 'form-item-list' && form[item.prop] != undefined
          "
        >
          <el-row :gutter="0">
            <el-col
              v-for="(subItem, subIndex) in form[item.prop]"
              :key="subIndex"
              :span="24 / form[item.prop].length"
            >
              <el-form-item
                :label="
                  labelFormatter(
                    item.insertIndex,
                    item.label,
                    (subIndex + 1).toString(),
                    item.type
                  )
                "
                label-width="150px"
              >
                <el-date-picker
                  v-if="item.formItemListType == 'el-date-picker'"
                  v-model="subItem[item.key]"
                  type="date"
                  style="width:150px"
                ></el-date-picker>
                <el-input-number
                  style="width:100%"
                  v-model="subItem[item.key]"
                  v-else-if="item.formItemListType === 'el-input-number'"
                  :precision="2"
                  :controls="false"
                  :min="0"
                  clearable
                  :disabled="item.isReadonly"
                ></el-input-number>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
      </div>
      <!-- submit -->
      <el-form-item>
        <el-button type="primary" @click="submitValidate()" id="submit-button"
          >提交</el-button
        >
      </el-form-item>
    </el-form>
  </el-row>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, reactive, ref } from "vue";
import { LandingAgency, Partners, Project } from "@/interface/entity";
import { FormPattern } from "@/interface/general";
import { useRoute, useRouter } from "vue-router";
import store from "@/store";
import { constObjs } from "@/const/const";
import { labelFormatter, uniqueArr } from "@/functions/general";
import { ElMessage, ElMessageBox } from "element-plus";

export default defineComponent({
  name: "MyForm",
  props: {
    formPattern: {
      // 从显式类型推断 props
      type: Object as PropType<FormPattern>,
      required: true
    },
    myForm: {
      type: Object,
      required: true
    },
    rules: {
      type: Object,
      required: true
    },
    // 子组件表单通过验证以后，执行父组件的表单提交操作
    validSubmit: {
      type: Function,
      required: true
    }
  },
  setup(props) {
    // 级联选择器变化
    const changeCascader = (val: never[]) => {
      console.log(val, props.myForm.formType);
    };
    // 表单验证ref
    const formRef = ref();
    // router
    const route = useRoute();
    const router = useRouter();
    // 当光标移动到合作方的选择器时，记录当前的值
    const prevSelectVal = ref<string>("");

    // 第一次使用选择器的时候触发focus事件
    const saveSlectPreval = (nowVal: string) => {
      prevSelectVal.value = nowVal;
    };
    // 修改技术方合作方式
    const changeSelect = (
      nowVal: string,
      prop: string,
      rowIndex: number,
      keyName: string
    ) => {
      ElMessageBox.confirm(
        `该操作将导致该项目对应所有 [收入流水] 的该技术方的 [分成] 重新计算，您确定将该技术方的分成计算方式修改为 [${nowVal}] 吗？`,
        "警告",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消"
        }
      )
        .then(() => {
          ElMessage({
            type: "success",
            message: `成功修改当前技术方分成计算方式为 [${nowVal}] ，提交保存后生效`
          });
        })
        .catch(() => {
          // 将props转换为ref，使得父组件传来的prop可以修改，也可以使用computed
          const tmp = ref(props.myForm);
          tmp.value[prop][rowIndex][keyName] = prevSelectVal.value;
          ElMessage({
            type: "info",
            message: `已还原当前技术方分成计算方式为【 ${prevSelectVal.value} 】`
          });
        });
    };

    // 获取搜索建议
    const querySearch = (
      queryString: string,
      cb: Function,
      prop: string,
      type: string,
      formType: string,
      index: number
    ) => {
      const querySearchResult = [] as { value: string }[];
      if (type == "multi") {
        // todo
        return;
      } else {
        // todo
        // if (formType == "project") {

        // }
        // 找出匹配的projectlist并选出其projectmanager构成一个字符串数组返回
        (store.state.tableData as object[])
          .filter(data =>
            (data[prop as keyof object] as string)
              .toLowerCase()
              .includes(queryString.toLowerCase())
          )
          .forEach(item => {
            querySearchResult.push({
              value: item[prop as keyof object] as string
            });
          });
      }
      // console.log(queryString, prop, type, formType);
      // console.log(
      //   "已去重",
      //   uniqueArr<{ value: string }>(querySearchResult, "value")
      // );
      // console.log("未去重", querySearchResult);
      // 把去重的结果给cb回调
      cb(uniqueArr<{ value: string }>(querySearchResult, "value"));
    };

    const submitValidate = async () => {
      try {
        await formRef.value.validate((valid: boolean) => {
          if (valid) {
            props.validSubmit();
            // 对store中的form重新赋默认值
            switch (route.name) {
              case "incomestreamsystem": {
                store.state.editingForm = JSON.parse(
                  JSON.stringify(constObjs.incomeStreamForm)
                );
                store.state.formPattern = JSON.parse(
                  JSON.stringify(constObjs.incomeStreamFormPattern)
                );
                break;
              }
              case "outlaystreamsystem": {
                store.state.editingForm = JSON.parse(
                  JSON.stringify(constObjs.outlayStreamForm)
                );
                store.state.formPattern = JSON.parse(
                  JSON.stringify(constObjs.outlayStreamFormPattern)
                );
                break;
              }
            }
          } else {
            ElMessage.error("提交失败");
          }
        });
      } catch (error) {
        console.log(error);
      }
    };

    // ------------multi-------------------
    // 为表单中的multi项添加row
    // todo client
    const addMultiItem = (prop: string) => {
      switch (prop) {
        case "clients": {
          ((store.state.editingForm as Project)
            .clients as LandingAgency[]).push({
            agencyName: "",
            shareRadio: 0,
            shareAmount: 0
          });
          break;
        }
        case "landingAgencies": {
          ((store.state.editingForm as Project)
            .landingAgencies as LandingAgency[]).push({
            agencyName: "",
            shareRadio: 0,
            shareAmount: 0
          });
          break;
        }
        case "partners": {
          ((store.state.editingForm as Project).partners as Partners[]).push({
            partnerName: "",
            shareRadio: 0,
            shareAmount: 0,
            caculation: "比例",
            partnerType: ""
          });
          break;
        }
      }
    };
    // 删除表单的eltable的row
    // todo client
    const deleteMultiItem = (prop: string, index: number) => {
      switch (prop) {
        case "clients": {
          ((store.state.editingForm as Project)
            .clients as LandingAgency[]).splice(index, 1);
          break;
        }
        case "landingAgencies": {
          ((store.state.editingForm as Project)
            .landingAgencies as LandingAgency[]).splice(index, 1);
          break;
        }
        case "partners": {
          ((store.state.editingForm as Project).partners as Partners[]).splice(
            index,
            1
          );
          break;
        }
      }
    };
    // ------------multi-------------------

    return reactive({
      changeSelect,
      saveSlectPreval,
      changeCascader,
      // 子组件获取父组件的参数并copy，保持reactive,让form object在子组件可以被修改
      form: computed(() => props.myForm),
      route,
      router,
      prevSelectVal,
      labelFormatter: computed(() => labelFormatter),
      querySearch,
      addMultiItem,
      deleteMultiItem,
      submitValidate,
      formRef
    });
  }
});
</script>

<style scoped>
#submit-button {
  margin-left: 32%;
}
.el-form {
  margin: 50px;
}
.el-col-1 > span {
  font-size: 20px;
}
.el-col-1 {
  line-height: 40px;
}
.el-autocomplete-suggestion__list {
  /* 选择器在一行显示 */
  display: block;
}
.el-input-number .el-input .el-input__inner {
  text-align: left;
}
input .el-input__inner {
  text-align: left;
}
/* 继承父亲宽度 */
.el-form-item__content .el-input-number,
.el-form-item__content .el-cascader,
.el-form-item__content .el-date-picker,
.el-form-item__content .el-autocomplete {
  width: 100%;
}
li {
  display: block;
}
.el-form-item__label,
.el-dialog__body {
  color: #000000;
}
</style>
